package com.it.zhangjun.arithmetic.队列.循环队列;


/**
 * @author zhangj
 * @description 循环队列，新增变量来区分队列是否已满
 * @date 2021-03-25 19:09
 */
public class MyCircularQueue1 {
    /**
     * 已经使用的元素个数
     */
    private int used = 0;
    /**
     * 第一个元素所在位置
     */
    private int front = 0;
    /**
     * 可存放的位置
     */
    private int rear;
    /**
     * 循环队列最多可以存放的元素个数
     */
    private int capacity;
    /**
     * 循环队列存储空间
     */
    private int[] a;

    public MyCircularQueue1(int k) {
        capacity = k;
        a = new int[k];
    }

    /**
     * 入队操作
     *
     * @param value
     * @return
     */
    public boolean enQueue(int value) {
        //如果已经放满了
        if (isFull()) {
            return false;
        }
        //没有满的话
        a[rear] = value;
        //已使用指针向后移动一位
        rear = (rear + 1) % capacity;
        //已使用空间+1
        used++;
        return true;
    }

    /**
     * 出队操作
     *
     * @return
     */
    public boolean deQueue() {
        //如果队列为空，不能出队
        if (isEmpty()) {
            return false;
        }
        //取出第一个元素
        int ret = a[front];
        //front指针向前移动一位
        front = (front + 1) % capacity;
        //已经使用的元素减一
        used--;
        return true;
    }

    /**
     * 得到队首元素，为空则返回-1
     *
     * @return
     */
    public int front() {
        //如果为空，不能取出队首元素
        if (isEmpty()) {
            return -1;
        }
        return a[front];
    }

    /**
     * 得到队尾元素，为空则返回-1
     *
     * @return
     */
    public int rear() {
        //如果为空，不能取出队尾元素
        if (isEmpty()) {
            return -1;
        }
        int tail = (rear - 1 + capacity) % capacity;
        return a[tail];
    }

    /**
     * 判断队列是否为空
     *
     * @return
     */
    private boolean isEmpty() {
        return used == 0;
    }

    /**
     * 判断是否已经满了
     *
     * @return
     */
    private boolean isFull() {
        return used == capacity;
    }
}